package com.newtouch.bxzs.business.train.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.bxzs.business.train.mapper.CourseMapper;
import com.newtouch.bxzs.business.train.mapper.UserCourseMapper;
import com.newtouch.bxzs.business.train.model.bo.CourseBO;
import com.newtouch.bxzs.business.train.model.bo.UserCourseBO;
import com.newtouch.bxzs.business.train.model.vo.CourseDetailVO;
import com.newtouch.bxzs.business.train.model.vo.CourseVO;
import com.newtouch.bxzs.business.train.service.CourseService;
import com.newtouch.bxzs.common.base.BaseErrorEnum;
import com.newtouch.bxzs.common.base.BaseException;
import com.newtouch.bxzs.common.base.em.ButtonTypeEnum;
import com.newtouch.bxzs.common.base.em.PublishStatusEnum;
import com.newtouch.bxzs.common.base.model.Course;
import com.newtouch.bxzs.common.base.model.UserCourse;
import com.newtouch.bxzs.common.base.util.CheckPublishDateUtils;
import com.newtouch.bxzs.common.base.util.UserDetailUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 课程管理service实现类
 *
 * <p>
 * <b>History:</b>
 * <table border="1">
 * <tr>
 * <th>Date</th>
 * <th>Operator</th>
 * <th>Memo</th>
 * </tr>
 * <tr>
 * <td>2021/2/22 10:10</td>
 * <td>dingqianbin</td>
 * <td>Create</td>
 * </tr>
 * </table>
 *
 * @author dingqianbin
 * @version 1.0.0
 * @since 1.0.0
 */
@Service
public class CourseServiceImpl implements CourseService {

    private static final Log logger = LogFactory.getLog(CourseServiceImpl.class);

    @Autowired
    CourseMapper courseMapper;

    @Autowired
    UserCourseMapper userCourseMapper;


    /**
     * 获取发布时间的最大限制
     */
    @Value("${publishTimeConfig.maxPublishTime}")
    private Integer maxPublishTime;

    /**
     * 获取撤销时间的最大限制
     */
    @Value("${revokeTimeConfig.maxRevokeTime}")
    private String maxRevokeTime;

    /**
     * 已发布状态码常量
     */
    private static final String PUBLISHED_STATUS = PublishStatusEnum.PUBLISHED_STATUS.getResultCode();
    /**
     * 未发布状态码常量
     */
    private static final String UNPUBLISHED_STATUS = PublishStatusEnum.UNPUBLISH_STATUS.getResultCode();
    /**
     * 已取消状态码常量
     */
    private static final String REVOKED_STATUS = PublishStatusEnum.REVOKED_STATUS.getResultCode();

    @Override
    public IPage<CourseBO> getCourseList(CourseVO courseVO) {
        Page<CourseBO> page = new Page<>(courseVO.getCurrentPage(), courseVO.getPageSize());
        return courseMapper.getCourseList(page, courseVO);
    }

    @Override
    public CourseBO getCourseDetail(String courseId) {
        if (StringUtils.isEmpty(courseId)) {
            logger.error("请求课程详细信息参数为空！");
            throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
        }
        CourseBO courseBO = courseMapper.getCourseDetail(courseId);
        UserCourse userCourse = userCourseMapper.selectOne(new QueryWrapper<UserCourse>().eq("COURSE_ID", courseId).eq("CREATE_USER_ID", Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId()));
        UserCourseBO userCourseBO = new UserCourseBO();
        if (!BeanUtil.isEmpty(userCourse)) {
            BeanUtil.copyProperties(userCourse, userCourseBO);
        }
        courseBO.setUserCourseBO(userCourseBO);
        return courseBO;
    }

    @Override
    public String modifyCourse(CourseDetailVO courseDetailVO) {
        /* 检查必填项 */
        if (StringUtils.isEmpty(courseDetailVO.getCourseTitle()) || StringUtils.isEmpty(courseDetailVO.getCourseType()) || StringUtils.isEmpty(courseDetailVO.getCourseIntroduction())) {
            logger.error("必填项为空！");
            throw new BaseException(BaseErrorEnum.REQUIRED_ITEM_NULL);
        }
        /* 效验发布时间和撤销时间是否正确 */
        if (courseDetailVO.getRevokeTime() != null || courseDetailVO.getPublishTime() != null) {
            /* 检验发布撤销时间 */
            CheckPublishDateUtils.checkDate(courseDetailVO.getPublishTime(), courseDetailVO.getRevokeTime(),
                    maxPublishTime, maxRevokeTime);
        }
        Course course = new Course();
        BeanUtil.copyProperties(courseDetailVO, course);
        Date date = new Date();
        String userId = Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId();
        course.setUpdateTime(date);
        course.setUpdateUserId(userId);
        /* 传入的按钮类型 */
        this.sendOrTemporary(courseDetailVO.getButtonType(), course);
        /* 如果课程ID不为空，则新增*/
        if (StringUtils.isEmpty(course.getCourseId())) {
            course.setCreateUserId(userId);
            course.setCreateTime(date);
            courseMapper.insert(course);
            logger.info("课程信息新增成功！");
        } else {
            courseMapper.update(course, new QueryWrapper<Course>().eq("COURSE_ID", course.getCourseId()));
            logger.info("课程信息修改成功！");
        }
        return course.getCourseId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer changeCourse(String courseId, String publishStatus) {
        /* 检查必传参数 */
        if (StringUtils.isEmpty(courseId) || StringUtils.isEmpty(publishStatus)) {
            logger.error("发布/撤销课程必传项为空");
            throw new BaseException(BaseErrorEnum.REQUIRED_ITEM_NULL);
        }
        Course course = new Course();
        Date date = new Date();
        /* 如果为撤销，则设置撤销时间 */
        if (REVOKED_STATUS.equals(publishStatus)) {
            /* 撤销课程的同时删除该课程关联的所有客户课程 */
            userCourseMapper.delete(new QueryWrapper<UserCourse>().eq("COURSE_ID", courseId));
            course.setRevokeTime(date);
        }
        /* 如果为发布，则设置发布时间 */
        if (PUBLISHED_STATUS.equals(publishStatus)) {
            course.setPublishTime(date);
        }
        /* 设置发布状态，修改人，和修改时间 */
        course.setPublishStatus(publishStatus);
        course.setUpdateUserId(Objects.requireNonNull(UserDetailUtil.getUserDetail()).getUserId());
        course.setUpdateTime(date);
        return courseMapper.update(course, new QueryWrapper<Course>().eq("COURSE_ID", courseId));
    }

    @Override
    public Integer deleteCourse(List<CourseDetailVO> courseDetailVOList) {
        /* 判断请求参数集合是否为空 */
        if (CollectionUtils.isEmpty(courseDetailVOList)) {
            logger.error("删除/批量删除课程请求参数为空");
            throw new BaseException(BaseErrorEnum.REQUEST_DATA_NULL);
        }
        int listSize = courseDetailVOList.size();
        /* 已发布的课程不允许删除，将已发布的课程移除集合 */
        courseDetailVOList.removeIf(courseDetailVO -> PUBLISHED_STATUS.equals(courseDetailVO.getPublishStatus()));
        List<String> courseIds = courseDetailVOList.stream().map(CourseDetailVO::getCourseId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(courseDetailVOList) && courseDetailVOList.size() == listSize && !CollectionUtils.isEmpty(courseIds)){
            return courseMapper.deleteBatchIds(courseIds);
        }else{
            logger.error("已发布的课程不允许删除！");
            throw new BaseException(BaseErrorEnum.PUBLISHED_COURSES_CANNOT_DELETE);
        }
    }

    /**
     * 发布/暂存
     *
     * @param buttonType 按钮类型
     * @param course 课程信息实体
     */
    private void sendOrTemporary(String buttonType, Course course) {
        /* 点击发布按钮 */
        if (buttonType.equals(ButtonTypeEnum.PUBLIC_BUTTON.getCode())) {
            /* 设置为已发布状态 */
            course.setPublishStatus(PUBLISHED_STATUS);
            course.setPublishTime(new Date());
        }
        /* 点击暂存按钮 */
        if (buttonType.equals(ButtonTypeEnum.TEMPORARY_BUTTON.getCode())) {
            /* 设置状态为未发布状态 */
            course.setPublishStatus(UNPUBLISHED_STATUS);
        }
    }
}

